package com.skyinno.mrms.utils;

import java.io.File;
import java.io.FileInputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.util.Map;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.io.IOUtils;
import org.apache.commons.lang.StringUtils;
import org.codehaus.jackson.JsonEncoding;
import org.codehaus.jackson.JsonGenerator;
import org.codehaus.jackson.map.ObjectMapper;
import org.springframework.util.Assert;
import org.springframework.util.ResourceUtils;
import org.springframework.web.servlet.view.AbstractView;

import com.skyinno.mrms.common.model.FileModel;
import com.skyinno.mrms.common.model.JsonModel;


public class DownloadView extends AbstractView {
    public static final String DEFAULT_CONTENT_TYPE = "application/octet-stream";

    public DownloadView() {
        this.setContentType(DEFAULT_CONTENT_TYPE);
        this.setExposePathVariables(false);
    }

    @Override
    protected void prepareResponse(HttpServletRequest request,
            HttpServletResponse response) {
        this.setResponseContentType(request, response);
    }

    @Override
    protected void renderMergedOutputModel(Map<String, Object> model,
            HttpServletRequest request, HttpServletResponse response)
            throws Exception {
        Object object = model.get(Constants.PAGE_DATE_ATTRIBUTE);
        if (object != null
                && JsonModel.class.isAssignableFrom(object.getClass())) {
            response.setContentType(PlainView.DEFAULT_CONTENT_TYPE);
            ObjectMapper objectMapper = new ObjectMapper();
            JsonGenerator generator = objectMapper.getJsonFactory()
                    .createJsonGenerator(response.getOutputStream(),
                            JsonEncoding.UTF8);
            objectMapper.writeValue(generator, object);
        } else {
            FileModel fm = null;
            Set<String> renderedAttributes = model.keySet();
            for (Map.Entry<String, Object> entry : model.entrySet()) {
                if (entry.getValue() instanceof FileModel
                        && renderedAttributes.contains(entry.getKey())) {
                    fm = (FileModel) entry.getValue();
                }
            }
            Assert.notNull(fm);
            Object source = fm.getSource();
            Assert.notNull(source);
            OutputStream os = response.getOutputStream();
            InputStream is = null;
            if (InputStream.class.isAssignableFrom(source.getClass())) {
                is = (InputStream) source;
            } else if (source instanceof File) {
                is = new FileInputStream((File) source);
            } else if (source instanceof String) {
                is = new FileInputStream(ResourceUtils.getFile((String) source));
            }
            if (is == null) {
                throw new IllegalArgumentException("source invalid");
            } else {
                response.setContentLength(is.available());
                String fn = fm.getFileName();
                response.addHeader("Content-Disposition",
                        "attachment;filename="
                                + (StringUtils.isBlank(fn) ? System
                                        .currentTimeMillis() : fn));
                IOUtils.copy(is, os);
                os.flush();
            }
        }
    }
}
